<?php

namespace App\Services;

/**
 * 简单模拟的浏览器客户端
 */
class Http
{

    protected $_url = null;
    protected $_post = false;
    protected $_params = null;
    protected $_timeout = 180;
    protected $_cookie = null;
    protected $_ua = 'Ku Http';
    protected $_cookie_file = '';
    protected $_save_cookie = '';
    protected $_header = 0;
    public static $delimiter = '';
    protected $_reurl = '';

    protected $_proxy = false;

    protected $_file = '';
    protected $_file_params = null;
    //    protected $_paramPost = false;

    /**
     * 设置请求URL
     *
     * @param string $url
     * @return \App\Services\Http
     */
    public function setUrl($url)
    {
        $this->_url = (string) $url;

        return $this;
    }

    public function setProxy($url)
    {
        $this->_proxy = $url;
        return $this;
    }

    /**
     * 设置Param 数据
     *
     * @param string|array $post
     * @return \App\Services\Http
     */
    //    public function setParam($_params, $isPost = false) {
    //        $this->_post = $isPost;
    //        if(isset($_params['inputStream'])){
    //            $_params['inputStream'] = new \CURLFFvile($_params['inputStream']);
    //        }
    //        if (is_array($_params)) {
    //            $this->_params = http_build_query($_params);
    //        } elseif (is_string($_params)) {
    //            $this->_params = \html_entity_decode($_params);
    //        }
    //
    //        return $this;
    //    }

    public function setParam($_params, $isPost = false, $isJson = false)
    {
        $this->_post = $isPost;
        if (isset($_params['inputStream'])) {
            if (class_exists('\CURLFile')) {
                //$this->_file = array('inputStream' => new \CURLFile(realpath($_params['inputStream']),$_params['mimetype'],$_params['savename']));
                $this->_file = array('inputStream' => curl_file_create(realpath($_params['inputStream']), $_params['mimetype'], $_params['savename']));
            } else {
                $this->_file = array('inputStream' => '@' . realpath($_params['inputStream']));
            }
            unset($_params['inputStream']);

            $this->_file_params = array_merge($_params, ['form-data' => $this->_file['inputStream']]);
            $this->_timeout = 100;
        }
        if ($isJson == true) {
            $this->_params = json_encode($_params);
        } else {
            if (is_array($_params)) {
                $this->_params = http_build_query($_params);
            } elseif (is_string($_params)) {
                $this->_params = \html_entity_decode($_params);
            }
        }
        if ($isJson) {
        }
        return $this;
    }

    public function geturl()
    {
        return $this->_url . '?' . $this->_params;
    }

    /**
     * 设置超时
     *
     * @param smallint $time
     * @return \App\Services\Http
     */
    public function setTimeout($time)
    {
        $this->_timeout = (int) $time;

        return $this;
    }

    /**
     * 设置COOKIE
     *
     * @param string $cookie
     * @return \App\Services\Http
     */
    public function setCookie($cookie)
    {
        $this->_cookie = (string) $cookie;

        return $this;
    }

    public function setUa($ua = null)
    {
        $this->_ua = trim($ua);
    }

    public function setHeader($header)
    {
        $this->_header = (array) $header;
    }

    public function setCookie_file($file = '')
    {
        $this->_cookie_file = $file;
    }

    public function setSave_Cookie($file = '')
    {
        $this->_save_cookie = $file;
    }

    /**
     * 发起一个CURL请求,模拟HTTP
     *
     * @return json|null|string|array|Object
     */
    public function send($proxy = false, $proxyUpdate = false)
    {
        $ch = curl_init();
        $url = $this->_url;
        if ((!$this->_post && $this->_params) or $this->_file) {
            $url = $this->_url . (strpos($this->_url, '?') ? '&' : '?') . $this->_params;
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        if ($this->_ua) {
            curl_setopt($ch, CURLOPT_USERAGENT, $this->_ua);
        }


        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $reurl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
        $this->_reurl = $reurl;
        //
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

        curl_setopt($ch, CURLOPT_TIMEOUT, $this->_timeout);
        if ($this->_header) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $this->_header);
        }
        if ($proxy) {
            $proxyUrl = 'http://webapi.http.zhimacangku.com/getip?num=1&type=1&pro=0&city=0&yys=0&port=1&time=1&ts=0&ys=0&cs=0&lb=1&sb=0&pb=4&mr=1&regions=110000,120000,130000,220000,310000,320000,330000,420000,430000';
            $redis = \Yaf\Registry::get('redis');
            $key = 'proxy.ip';
            $server = $redis->get($key);
            if ($proxyUpdate || empty($server)) {
                $server = trim(file_get_contents($proxyUrl));
                $redis->set($key, $server);
                $redis->expire($key, 300);
            }
            if ($server) {
                curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false);
                curl_setopt($ch, CURLOPT_PROXYTYPE, 0); //sock5
                curl_setopt($ch, CURLOPT_PROXY, $server);
                // 设置隧道验证信息
                curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
            }
        }

        if (!empty($this->_cookie)) {
            curl_setopt($ch, CURLOPT_COOKIE, $this->_cookie);
        }
        if (!empty($this->_save_cookie)) {
            curl_setopt($ch, CURLOPT_COOKIEJAR, $this->_save_cookie); //存储cookies
        }
        if (!empty($this->_cookie_file)) {
            curl_setopt($ch, CURLOPT_COOKIEFILE, $this->_cookie_file); //将cookies带入请求
        }
        curl_setopt($ch, CURLOPT_ACCEPT_ENCODING, "gzip,deflate");
        if ($this->_post) {
            // post数据
            curl_setopt($ch, CURLOPT_POST, 1);

            if ($this->_file) {
                //curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_file['inputStream']);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_file_params);
            } else {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_params);
            }
        }
        $response = curl_exec($ch);
        $msg = curl_error($ch);
        if ($msg) {
            var_dump($msg);
            \Ku\Tool::debugDD($url . ':error:' . $msg, __METHOD__, __LINE__);
        }
        curl_close($ch);
        $this->reset();

        return $response;
    }


    public function postJson()
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->_url);
        curl_setopt($ch, CURLOPT_POST, 1);
        //        var_dump($this->_params);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_params);
        $dataLen = strlen($this->_params);
        //        var_dump($dataLen);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt(
            $ch,
            CURLOPT_HTTPHEADER,
            array(
                'Content-Type: application/json',
                'Content-Length: ' . $dataLen
            )
        );
        if (!empty($this->_cookie)) {
            curl_setopt($ch, CURLOPT_COOKIE, $this->_cookie);
        }
        $response = curl_exec($ch);
        curl_close($ch);
        $this->reset();
        return $response;
    }

    /**
     * 获取url页面内容
     * @return mixed
     */
    public function getHtml()
    {
        $UserAgent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022; .NET CLR 1.0.3705; .NET CLR 1.1.4322)';
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $this->_url);
        curl_setopt($curl, CURLOPT_HEADER, 0);  //0表示不输出Header，1表示输出
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_ENCODING, '');
        curl_setopt($curl, CURLOPT_USERAGENT, $UserAgent);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        $data['html'] = curl_exec($curl);
        $data['status'] = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        $this->reset();
        return $data;
    }

    public function getReurl()
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->_url);
        curl_setopt($ch, CURLOPT_NOBODY, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_exec($ch);
        $info = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
        curl_close($ch);
        $this->reset();
        return $info;
    }

    public function putPart($params)
    {

        self::$delimiter = uniqid();
        $post_data = static::buildData($params);
        $curl = curl_init($this->_url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($curl, CURLOPT_HTTPHEADER, [
            "Content-Type: multipart/form-data; boundary=" . static::$delimiter,
            "Content-Length: " . strlen($post_data)
        ]);
        $response = curl_exec($curl);
        curl_close($curl);
        return $response;
    }
    //编译请求头格式和数据流   
    private static function buildData($param)
    {
        $data = '';
        $eol = "\r\n";
        $upload = $param['media'];
        unset($param['media']);
        foreach ($param as $name => $content) {
            $data .= "--" . static::$delimiter . "\r\n"
                . 'Content-Disposition: form-data; name="' . $name . "\"\r\n\r\n" . $content . "\r\n";
        }
        $data .= "--" . static::$delimiter . $eol
            . 'Content-Disposition: form-data; name="media"; filename="' . $param['filename'] . '"' . "\r\n" . 'Content-Type:application/octet-stream' . "\r\n\r\n";
        $data .= $upload . "\r\n";
        $data .= "--" . static::$delimiter . "--\r\n";
        return $data;
    }
    /**
     * 重置
     */
    protected function reset()
    {
        $this->_url = null;
        $this->_post = false;
        $this->_postFields = null;
        $this->_params = null;
        $this->_timeout = 1;
        $this->_save_cookie = null;
        $this->_header = null;
        $this->_cookie_file = null;
        $this->_cookie = null;
        $this->_file = null;
        $this->_reurl = null;
        //        $this->_paramPost = false;
    }
}